package confInfo;

import java.util.*;
import javax.servlet.http.*;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Attribute;
import java.util.List;
import java.util.Iterator;
import org.dom4j.io.XMLWriter;
import java.io.*;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader; 
import org.dom4j.DocumentHelper;
import producers.*;
import io.Outputer;

public class ConfBean {

	final Constants con = new Constants();
	private static int id = 0;
	final String CONFIGURE_FILE = "configure.xml";
	String configurePath;
	private Document document;
	private final String NULL_NODE = "null";
	public String domain;
	   
	public static ArrayList<ArrayList<ItemBean>> levelsItems = new ArrayList<ArrayList<ItemBean>>();
	static{
		for(int i=0;i<Constants.getLevelCount();i++){
			levelsItems.add(new ArrayList<ItemBean>());
		}
	}
	
	public static int getID(){
		id++;
		return id - 1;
	}
	
	public void setDomain(String s){
		this.domain = s;
	}
	public String getDomain(){
		return this.domain;
	}
	public void setPath(String s){
		configurePath = s + CONFIGURE_FILE;
		System.out.println("configure path:" + configurePath);
	}
	public String getPath(){
		return configurePath;
	}
	
	public ArrayList<ArrayList<ItemBean>> getLevelsItems(){
		return levelsItems;
	}
//	public ArrayList<ItemBean> getlevel1Items(){
//		return this.level1Items;
//	}
//	public ArrayList<ItemBean> getlevel2Items(){
//		return this.level2Items;
//	}
//	public ArrayList<ItemBean> getlevel3Items(){
//		return this.level3Items;
//	}
	
	public void addItem(String level, ItemBean i){
		Constants.level l = Constants.level.valueOf(level);
		i.setLevel(level);
		switch(l){
		case start_url: levelsItems.get(0).add(i);break;
		case rule: levelsItems.get(1).add(i);break;
		case level1: levelsItems.get(2).add(i);break;
		case level2: levelsItems.get(3).add(i);break;
		case level3: levelsItems.get(4).add(i);break;
		case item: levelsItems.get(5).add(i);break;
		default: System.out.println("undefine level:" + level);
		}
		
//		if(level=="level1"){
//			levelsItems.get(0).add(i);
//		}else if(level=="level2"){
//			levelsItems.get(1).add(i);
//		}else if(level=="level3"){
//			levelsItems.get(2).add(i);
//		}else{
//			System.out.println("undefine level: " + level);
//		}
	}
	public void addItem(String level, String key, String value){
		ItemBean i = new ItemBean();
		i.setKey(key);
		i.setLevel(level);
		i.setValue(value);
		this.addItem(level, i);
	}
	public void test(){
		addItem("level1", "key1", "value1");
		addItem("level2", "key2", "value2");
	}
	
	public void delete(int id){
		for(Iterator<ArrayList<ItemBean>> it = levelsItems.iterator();it.hasNext(); ){
			for(Iterator<ItemBean> i = it.next().iterator();i.hasNext();){
				if(i.next().getId().equals(String.valueOf(id))){
					i.remove();
				}
			}
		}
	}
	
	public boolean save(HttpServletRequest request){
		this.setDomain(request.getParameter("domain"));
		for(Iterator<ArrayList<ItemBean>> it = levelsItems.iterator();it.hasNext(); ){
			for(Iterator<ItemBean> i = it.next().iterator();i.hasNext();){
				ItemBean ib = i.next();
				String id = ib.getId();
				ib.setKey(request.getParameter(id+"key"));
				ib.setValue(request.getParameter(id+"value"));
				System.out.println("save "+request.getParameter(id+"key")+":"+request.getParameter(id+"value"));
			}
		}
		System.out.println("-------------");
		return true;
	}
	
	public boolean saveAndGenerateXML(HttpServletRequest request){
		this.save(request);
		Document document = DocumentHelper.createDocument();
		Element configElement = document.addElement("config");
		Element domainElement = configElement.addElement("domain");
		domainElement.setText(this.domain);
		int level = 1;
		for(Iterator<ArrayList<ItemBean>> it = levelsItems.iterator();it.hasNext(); ){
			Element levelElement = configElement.addElement(Constants.getLevel(level));
			level++;
			for(Iterator<ItemBean> i = it.next().iterator();i.hasNext();){
				ItemBean ib = i.next();
				String id = ib.getId();
				ib.setKey(request.getParameter(id+"key"));
				ib.setValue(request.getParameter(id+"value"));
				if(ib.getKey()==null||ib.getKey()==""){
					Element keyElement = levelElement.addElement(NULL_NODE);
					keyElement.setText(request.getParameter(id+"value"));
					continue;
				}
				Element keyElement = levelElement.addElement(request.getParameter(id+"key"));
				keyElement.setText(request.getParameter(id+"value"));
				System.out.println("save "+request.getParameter(id+"key")+":"+request.getParameter(id+"value"));
			}
		}
		System.out.println("-------------");
	    try {
			XMLWriter output = new XMLWriter(new FileWriter(new File(
					configurePath)));
			document.addDocType("config", null, null);
			output.write("");
			output.write(document);
			output.close();
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
		return true;
	}
	
	public void parseXml(String file){
		 try{
			   this.clear();
			   SAXReader saxReader = new SAXReader();
			   Document document = saxReader.read(file);
			   Element domain = (Element)document.selectSingleNode("//domain");
			   this.setDomain(domain.getText());
			   
			   for(int level=1;level<Constants.getLevelCount()+1;level++){
				   List l = document.selectNodes("//"+Constants.getLevel(level)+"/*");
				   Iterator iter=l.iterator();
				   while(iter.hasNext()){
					   Element e = (Element)iter.next();
					   if(e.getName()==NULL_NODE){
						   this.addItem(Constants.getLevel(level), "", e.getText());
						   System.out.println("add null item");
						   continue;
					   }
					   this.addItem(Constants.getLevel(level), e.getName(), e.getText());
					   System.out.println("add item:"+ Constants.getLevel(level) + " " + 
							   e.getName()+" " + e.getText());
				   }
				   
			   }
		 }catch(Exception e){
             e.printStackTrace();
         }
	}
	
	public void generate(){
		System.out.println("begin generate:");
		//generate items.py
		ArrayList<ItemBean> ibs = levelsItems.get(levelsItems.size()-1);
		ArrayList<String> ss = new ArrayList<String>();
		for(ItemBean ib: ibs){
			ss.add(ib.getKey());
		}
		ItemProducer ip = new ItemProducer(con.PROJECT_NAME, ss);
		Outputer.output(con.ITEMS_FILE, ip.produce());
		System.out.println("generate "+con.ITEMS_FILE +" ok");
		
		//generate pipelines.py
		PipelineProducer pp = new PipelineProducer(con.PROJECT_NAME);
		Outputer.output(con.PIPELINES_FILE, pp.produce());
		System.out.println("generate "+con.PIPELINES_FILE +" ok");
		
		//generate setting.py
		SettingProducer sp = new SettingProducer(con.PROJECT_NAME);
		Outputer.output(con.SETTING_FILE, sp.produce());
		System.out.println("generate "+con.SETTING_FILE +" ok");
		
		//generate spider.py
		SpiderProducer spp = new SpiderProducer(con.PROJECT_NAME, this);
		Outputer.output(con.SPIDER_FILE, spp.produce());
		System.out.println("generate "+con.SPIDER_FILE +" ok");
	}
	public void clear(){
		for(int i=0;i<Constants.getLevelCount();i++){
			levelsItems.get(i).clear();
		}
	}
	public String encode(String s){
		return s.replace(":", "@@@");
	}
	public String decode(String s){
		return s.replace("@@@", ":");
	}
}
